package com.novel.demo;

import com.github.rholder.retry.*;
import com.google.common.base.Predicates;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;


@Service
@Slf4j
public class RetryService {

    static int count = 1;

    public void retry() {

        long startTime = System.currentTimeMillis();
        Boolean result = null;

        /**
         * 定义重试机制
         */
        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                .retryIfException()
                .retryIfRuntimeException()
                .retryIfExceptionOfType(Exception.class)
                .retryIfException(Predicates.equalTo(new Exception()))
                .retryIfResult(Predicates.equalTo(false))
                .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                .withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(4, TimeUnit.SECONDS))
                .build();

        /**
         * 封装要执行的任务
         */
        Callable<Boolean> callable = new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                Thread.sleep(500);
                if (count == 3) {
                    return true;
                }
                System.out.println(count);
                count++;
                return false;
            }
        };

        /**
         * 开始执行
         */
        try {
            result = retryer.call(callable);
        } catch (Exception e) {
            e.printStackTrace();
        }

        /**
         * 后续结果输出
         */
        System.out.println(result);
        long endTime = System.currentTimeMillis();
        System.out.println("用时:" + (endTime - startTime) + "毫秒");
    }

    public static void main(String[] args) {
        new RetryService().retry();
    }
}